Micron Document
C.S.Burner 🪙 ━►🔥GIT Node

Node / reticulum_mirror / MeshChatX / files / meshchatx / src / frontend / components / rnode / RNodeDeviceSelector.vue

Displaying Raw • Download

meshchatx/src/frontend/components/rnode/RNodeDeviceSelector.vue 65ca9ddc823fcc2c8f8653c553b944b85db0875f (65ca9ddc) Text, 7.91 KB

T8b949e<!-- SPDX-License-Identifier: 0BSD -->

Tff7b72<templateTff7b72>
Tff7b72<div Te6edf3class=Ta5d6ff"Ta5d6ffspace-y-4Ta5d6ff"Tff7b72>
Tff7b72<div Te6edf3class=Ta5d6ff"Ta5d6ffflex items-center gap-2Ta5d6ff"Tff7b72>
Tff7b72<div Te6edf3class=Ta5d6ff"Ta5d6ffp-2 bg-blue-100 dark:bg-blue-900/30 rounded-lg text-blue-600 dark:text-blue-400 shrink-0Ta5d6ff"Tff7b72>
Tff7b72<MaterialDesignIcon Te6edf3icon-name=Ta5d6ff"Ta5d6ffusb-portTa5d6ff" Te6edf3class=Ta5d6ff"Ta5d6ffsize-5Ta5d6ff" Tff7b72/>
Tff7b72</div>
Tff7b72<h2 Te6edf3class=Ta5d6ff"Ta5d6fffont-bold text-gray-900 dark:text-zinc-100Ta5d6ff"Tff7b72>
{{ stepNumber }}. {{ Te6edf3$t("tools.rnode_flasher.select_device") }}
Tff7b72</h2>
Tff7b72</div>

Tff7b72<div Te6edf3class=Ta5d6ff"Ta5d6ffspace-y-1Ta5d6ff"Tff7b72>
Tff7b72<label Te6edf3class=Ta5d6ff"Ta5d6ffrnf-labelTa5d6ff"Tff7b72>{{ Te6edf3$t("tools.rnode_flasher.connection_method") }}Tff7b72</label>
Tff7b72<div Te6edf3class=Ta5d6ff"Ta5d6ffgrid grid-cols-3 gap-2Ta5d6ff"Tff7b72>
Tff7b72<button
Te6edf3v-for=Ta5d6ff"Ta5d6ffoption in connectionOptionsTa5d6ff"
Te6edf3:key=Ta5d6ff"Ta5d6ffoption.idTa5d6ff"
Te6edf3type=Ta5d6ff"Ta5d6ffbuttonTa5d6ff"
Te6edf3:data-testid=Ta5d6ff"Ta5d6ff`rnode-transport-Tff7b72${Te6edf3optionTff7b72.Td2a8ffidTff7b72}Ta5d6ff`Ta5d6ff"
Te6edf3:disabled=Ta5d6ff"Ta5d6ff!option.availableTa5d6ff"
Te6edf3class=Ta5d6ff"Ta5d6ffflex flex-col items-center justify-center gap-1 py-2.5 px-2 rounded-xl border text-xs sm:text-sm font-bold transition-allTa5d6ff"
Te6edf3:class=Ta5d6ff"
Ta5d6ff connectionMethod === option.id
? Ta5d6ff'Ta5d6ffbg-blue-600 text-white border-blue-600Ta5d6ff'
Ta5d6ff : option.available
? Ta5d6ff'Ta5d6ffbg-gray-50 dark:bg-zinc-800/50 border-gray-200 dark:border-zinc-800 text-gray-700 dark:text-zinc-300 hover:bg-gray-100 dark:hover:bg-zinc-800Ta5d6ff'
Ta5d6ff : Ta5d6ff'Ta5d6ffbg-gray-100 dark:bg-zinc-900 border-gray-200 dark:border-zinc-800 text-gray-400 dark:text-zinc-600 cursor-not-allowedTa5d6ff'
Ta5d6ff Ta5d6ff"
@Te6edf3click=Ta5d6ff"Ta5d6ffoption.available && Te6edf3$emitTa5d6ff(Ta5d6ff'Ta5d6ffupdate:connectionMethodTa5d6ff'Ta5d6ff, option.id)Ta5d6ff"
Tff7b72>
Tff7b72<MaterialDesignIcon Te6edf3:icon-name=Ta5d6ff"Ta5d6ffoption.iconTa5d6ff" Te6edf3class=Ta5d6ff"Ta5d6ffsize-4 sm:size-5Ta5d6ff" Tff7b72/>
Tff7b72<spanTff7b72>{{ Te6edf3$t(option.labelKey) }}Tff7b72</span>
Tff7b72</button>
Tff7b72</div>
Tff7b72</div>

Tff7b72<div Te6edf3v-if=Ta5d6ff"Ta5d6ffconnectionMethod === Ta5d6ff'Ta5d6ffwifiTa5d6ff'Ta5d6ff" Te6edf3class=Ta5d6ff"Ta5d6ffspace-y-1Ta5d6ff"Tff7b72>
Tff7b72<label Te6edf3class=Ta5d6ff"Ta5d6ffrnf-labelTa5d6ff"Tff7b72>{{ Te6edf3$t("tools.rnode_flasher.ip_address") }}Tff7b72</label>
Tff7b72<input
Te6edf3:value=Ta5d6ff"Ta5d6ffwifiHostTa5d6ff"
Te6edf3type=Ta5d6ff"Ta5d6fftextTa5d6ff"
Te6edf3inputmode=Ta5d6ff"Ta5d6ffdecimalTa5d6ff"
Te6edf3autocomplete=Ta5d6ff"Ta5d6ffoffTa5d6ff"
Te6edf3spellcheck=Ta5d6ff"Ta5d6fffalseTa5d6ff"
Te6edf3class=Ta5d6ff"Ta5d6ffrnf-inputTa5d6ff"
Te6edf3:placeholder=Ta5d6ff"Te6edf3$tTa5d6ff(Ta5d6ff'Ta5d6fftools.rnode_flasher.ip_address_placeholderTa5d6ff'Ta5d6ff)Ta5d6ff"
@Te6edf3input=Ta5d6ff"Te6edf3$emitTa5d6ff(Ta5d6ff'Ta5d6ffupdate:wifiHostTa5d6ff'Ta5d6ff, Te6edf3$event.target.valueTa5d6ff)Ta5d6ff"
Tff7b72/>
Tff7b72<p Te6edf3class=Ta5d6ff"Ta5d6fftext-[10px] text-gray-500 dark:text-zinc-500Ta5d6ff"Tff7b72>
{{ Te6edf3$t("tools.rnode_flasher.wifi_help") }}
Tff7b72</p>
Tff7b72</div>

Tff7b72<div Te6edf3class=Ta5d6ff"Ta5d6ffspace-y-1Ta5d6ff"Tff7b72>
Tff7b72<label Te6edf3class=Ta5d6ff"Ta5d6ffrnf-labelTa5d6ff"Tff7b72>{{ Te6edf3$t("tools.rnode_flasher.product") }}Tff7b72</label>
Tff7b72<select Te6edf3:value=Ta5d6ff"Ta5d6ffselectedProduct?.id ?? Ta5d6ff'Ta5d6ff'Ta5d6ff" Te6edf3class=Ta5d6ff"Ta5d6ffrnf-inputTa5d6ff" @Te6edf3change=Ta5d6ff"Ta5d6ffonProductChangeTa5d6ff"Tff7b72>
Tff7b72<option Te6edf3value=Ta5d6ff"Ta5d6ff" disabledTff7b72>{{ Te6edf3$t("tools.rnode_flasher.select_product") }}Tff7b72</option>
Tff7b72<option Te6edf3v-for=Ta5d6ff"Ta5d6ffproduct in productsTa5d6ff" Te6edf3:key=Ta5d6ff"Ta5d6ffproduct.idTa5d6ff" Te6edf3:value=Ta5d6ff"Ta5d6ffproduct.idTa5d6ff"Tff7b72>
{{ product.name }}
Tff7b72</option>
Tff7b72</select>
Tff7b72</div>

Tff7b72<div Te6edf3class=Ta5d6ff"Ta5d6ffspace-y-1Ta5d6ff"Tff7b72>
Tff7b72<label Te6edf3class=Ta5d6ff"Ta5d6ffrnf-labelTa5d6ff"Tff7b72>{{ Te6edf3$t("tools.rnode_flasher.model") }}Tff7b72</label>
Tff7b72<select
Te6edf3:value=Ta5d6ff"Ta5d6ffselectedModel?.id ?? Ta5d6ff'Ta5d6ff'Ta5d6ff"
Te6edf3:disabled=Ta5d6ff"Ta5d6ff!selectedProductTa5d6ff"
Te6edf3class=Ta5d6ff"Ta5d6ffrnf-input disabled:opacity-50Ta5d6ff"
@Te6edf3change=Ta5d6ff"Ta5d6ffonModelChangeTa5d6ff"
Tff7b72>
Tff7b72<option Te6edf3value=Ta5d6ff"Ta5d6ff" disabledTff7b72>{{ Te6edf3$t("tools.rnode_flasher.select_model") }}Tff7b72</option>
Tff7b72<template Te6edf3v-if=Ta5d6ff"Ta5d6ffselectedProductTa5d6ff"Tff7b72>
Tff7b72<option Te6edf3v-for=Ta5d6ff"Ta5d6ffmodel in selectedProduct.modelsTa5d6ff" Te6edf3:key=Ta5d6ff"Ta5d6ffmodel.idTa5d6ff" Te6edf3:value=Ta5d6ff"Ta5d6ffmodel.idTa5d6ff"Tff7b72>
{{ model.name }}
Tff7b72</option>
Tff7b72</template>
Tff7b72</select>
Tff7b72</div>

Tff7b72<button
Te6edf3v-if=Ta5d6ff"Ta5d6ffselectedProduct?.platform === 0x70 && connectionMethod === Ta5d6ff'Ta5d6ffserialTa5d6ff'Ta5d6ff"
Te6edf3:disabled=Ta5d6ff"Ta5d6ffisEnteringDfuModeTa5d6ff"
Te6edf3class=Ta5d6ff"Ta5d6ffw-full inline-flex items-center justify-center gap-2 rounded-xl bg-amber-100 dark:bg-amber-900/30 hover:bg-amber-200 dark:hover:bg-amber-900/40 px-4 py-2.5 text-sm font-bold text-amber-700 dark:text-amber-400 transition-colors disabled:opacity-50Ta5d6ff"
@Te6edf3click=Ta5d6ff"Te6edf3$emitTa5d6ff(Ta5d6ff'Ta5d6ffenter-dfuTa5d6ff'Ta5d6ff)Ta5d6ff"
Tff7b72>
Tff7b72<v-progress-circular Te6edf3v-if=Ta5d6ff"Ta5d6ffisEnteringDfuModeTa5d6ff" indeterminate Te6edf3size=Ta5d6ff"Ta5d6ff16Ta5d6ff" Te6edf3width=Ta5d6ff"Ta5d6ff2Ta5d6ff" Tff7b72/>
Tff7b72<MaterialDesignIcon v-else Te6edf3icon-name=Ta5d6ff"Ta5d6ffrestart-alertTa5d6ff" Te6edf3class=Ta5d6ff"Ta5d6ffsize-4Ta5d6ff" Tff7b72/>
Tff7b72<spanTff7b72>
{{
isEnteringDfuMode
? Te6edf3$t("tools.rnode_flasher.entering_dfu_mode")
: Te6edf3$t("tools.rnode_flasher.enter_dfu_mode")
}}
Tff7b72</span>
Tff7b72</button>
Tff7b72</div>
Tff7b72</template>

Tff7b72<scriptTff7b72>
import MaterialDesignIcon from "../MaterialDesignIcon.vue";

export default {
name: "RNodeDeviceSelector",
components: { MaterialDesignIcon },
props: {
stepNumber: { type: Number, default: 1 },
connectionMethod: { type: String, required: true },
wifiHost: { type: String, default: "" },
selectedProduct: { type: Object, default: null },
selectedModel: { type: Object, default: null },
products: { type: Array, required: true },
capabilities: { type: Object, required: true },
isEnteringDfuMode: { type: Boolean, default: false },
},
emits: [
"update:connectionMethod",
"update:wifiHost",
"update:selectedProduct",
"update:selectedModel",
"enter-dfu",
],
computed: {
connectionOptions() {
const t = this.capabilities?.transports || {};
return [
{
id: "serial",
labelKey: "tools.rnode_flasher.serial",
icon: "usb-port",
available: Boolean(t.serial?.available),
},
{
id: "bluetooth",
labelKey: "tools.rnode_flasher.bluetooth",
icon: "bluetooth",
available: Boolean(t.bluetooth?.available),
},
{
id: "wifi",
labelKey: "tools.rnode_flasher.wifi",
icon: "wifi",
available: Boolean(t.wifi?.available),
},
];
},
},
methods: {
onProductChange(event) {
const id = event.target.value;
const product = this.products.find((p) => String(p.id) === String(id)) || null;
this.$emit("update:selectedProduct", product);
this.$emit("update:selectedModel", null);
},
onModelChange(event) {
const id = event.target.value;
const model = this.selectedProduct?.models?.find((m) => String(m.id) === String(id)) || null;
this.$emit("update:selectedModel", model);
},
},
};
Tff7b72</script>

Tff7b72<style scopedTff7b72>
@reference "../../style.css";
.rnf-label {
@apply text-xs font-semibold text-gray-500 dark:text-zinc-500 uppercase tracking-wider;
}
.rnf-input {
@apply w-full bg-gray-50 dark:bg-zinc-800/50 border border-gray-200 dark:border-zinc-800 text-gray-900 dark:text-zinc-100 text-sm rounded-xl focus:ring-2 focus:ring-blue-500/50 focus:border-blue-500 px-4 py-2.5 transition-all;
}
select.rnf-input {
appearance: none;
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
background-position: right 0.5rem center;
background-repeat: no-repeat;
background-size: 1.5em 1.5em;
padding-right: 2.5rem;
}
Tff7b72</style>

Served by rngit 1.5.2 - Generated in 0.03s